<?php
/**
 * Created by PhpStorm.
 * User: Korbin
 * Date: 2018/11/10
 * Time: 15:37
 */

namespace app\script\command;

use app\common\model\DataVideo;
use app\common\model\Job;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;

class Vmate extends Base
{

    private $listKey = 'data';//获取数据区域
    private $startUrl = 'http://vapi.apk.vmate.in/v1/ugc_feed?login_status=0&fr=android&pv=3.1&uuid=974100ab-df10-41eb-9057-9f6970c8a0bf&encrypt=1&ds=9nOKPYfSVDj627LTRfX2kq%2F01d6FnT8OtDT%2B7N8njLc%3D%0A&sv=beta&gid=c3fe598c-b017-4f75-848b-02dcbe2f2e31&appver=1.89&ve=1.89&ni=9nOKPYfSVDj627LTRfX2kq%2F01d6FnT8OtDT%2B7N8njLc%3D%0A&android_id=995fa82082daf5f8&_tm=1541498146520&sign=d4a8caae62dbecd4fa8dcfb32778632b&appname=vmate_app&appid=com.uc.vmate.app.gp&network_type=WIFI&location=OTHERS&uc_param_str=chcpfrlaminintpfprpvssvesvds&language=en&la=en&falcon_ver=1000&ver=1.89&refresh_flag=normal&lon=0.0&mi=SM-C7100&ch=com.uc.vmate.app.gp&iflow_login=0&entry=app&location_time=0&pf=199&sver=beta&adapter=vmate&nt=WIFI&lang=english&set_lang=english&na=cn&page=1&geo_time=0&ss=1080x1920&slot=UGCVideoFeed&apiver=4&clientid=2ede0da0-315f-432c-a246-982c0660578a&osver=25&app=vmate_app&country=cn&ct_lang=english&lat=0.0&pr=Tudoo&cp=cc%3AIN%3Bna%3A%25E5%258D%25B0%25E5%25BA%25A6';

    /**
     * 设置执行名称及配置传入参数、脚本描述
     */
    protected function configure()
    {
        //设置执行名称
        $this->setName('vmateVideo')
            ->addOption('job', 'j', Option::VALUE_OPTIONAL)
            ->setDescription('Run all the time');
    }

    /*********************公用验证部分************************************/
    /*
     * 执行脚本任务
     *
     * @param Input $input
     * @param Output $output
     */
    protected function execute(Input $input, Output $output)
    {
        $job = $input->getOption('job');
        if (empty($job)) {
            $output->writeln('请传入执行任务ID：' . date('Y-m-d H:i:s'));
            exit();
        }

        $output->writeln('脚本开始：' . date('Y-m-d H:i:s'));
        $jobModel = new Job();
        $jobInfo = $jobModel->where(['id' => $job])->find();//获取任务配置信息
        if (empty($jobInfo)) {
            $output->writeln('任务ID不存在：' . date('Y-m-d H:i:s'));
            exit();
        } else {
            $jobInfo = $jobInfo->toArray();
        }
        $jobRedisInfo = $this->redis->hGet('jobHash', $job);//获取任务redis记录
        if (empty($jobRedisInfo)) {
            $jobRedisData = [
                'planned_quantity' => $jobInfo['planned_quantity'],
                'real_quantity' => (empty($jobInfo['real_quantity']) ? 0 : $jobInfo['real_quantity']),
                'shortvideo_num' => (empty($jobInfo['shortvideo_num']) ? 0 : $jobInfo['shortvideo_num']),
                'smallvideo_num' => (empty($jobInfo['smallvideo_num']) ? 0 : $jobInfo['smallvideo_num']),
                'finsh_time' => '',
            ];
        } else {
            $jobRedisData = json_decode($jobRedisInfo, true);
            $jobRedisData['planned_quantity'] = $jobInfo['planned_quantity'];
        }

        //开始循环执行采集任务
        while (true) {
            //采集开始执行验证采集开关是否打开
            $jobStatus = $this->redis->hGet('job_status', $job);
            if ($jobStatus != 1) {
                break;//采集开关关闭时跳出循环结束脚本执行
            }

            $result = $this->getApiData();//获取采集源结果

            //验证是否有相应的采集数据
            if (array_key_exists($this->listKey, $result)) {
                $lists = $result[$this->listKey];
            } else {
                $output->writeln($this->getName().'采集源服务器出错或找不到采集信息！'.date('Y-m-d H:i:s'));
                continue;
            }

            //开始拼装数据
            $insertData = [];
            if (!empty($lists)) {
                $this->createData($lists, $jobInfo, $jobRedisData, $insertData);//对源数据进行对应入库
                if (!empty($insertData)) {
                    //当实际采集数据大于等于计划采集数据量时设置redis开关值
                    if (($jobRedisData['planned_quantity'] - $jobRedisData['real_quantity']) <= 0) {
                        $this->redis->hSet('job_status', $job, 2);//正常完成值为2
                        $jobRedisData['finsh_time'] = date('Y-m-d H:i:s');//正常完成时间记录
                        $jobModel->save(['job_status'=>2,'status_time'=>date('Y-m-d H:i:s')],['id'=>$job]);
                    }
                    $this->redis->hSet('jobHash', $job, json_encode($jobRedisData));
                    $output->writeln('【'.$this->getName().'采集成功】本次采集入库数据条数为【' . count($insertData) . '】'.date('Y-m-d H:i:s'));
                } else {
                    $output->writeln('【'.$this->getName().'执行成功】本次采集无符合要求的数据入库!'.date('Y-m-d H:i:s'));
                }
            } else {
                $output->writeln('【'.$this->getName().'请求成功】本次请求无返回正确数据!'.date('Y-m-d H:i:s'));
                continue;
            }

            //间隔随机时间
            $sleep = rand(5, 10);
            sleep($sleep);
        }

        $output->writeln($this->getName().'任务执行完毕：' . date('Y-m-d H:i:s'));
    }
    /*********************公用验证部分************************************/

    /**
     * 组装url进行数据获取
     *
     * @return mixed
     */
    private function getApiData()
    {
        $result = curl_get_https($this->startUrl);
        $result = json_decode($result, true);
        return $result;
    }

    /**
     * 采集数据拼装入库
     *
     * @param $lists
     * @param $jobInfo
     * @param $jobRedisData
     * @param $insertData
     */
    private function createData($lists, $jobInfo, &$jobRedisData, &$insertData)
    {
        $updateData=[];
        $lists = json_decode($this->parseAes($lists),true);
        $video = new DataVideo();
        foreach ($lists as $val) {
            if($val['type'] != 'video'){
                continue;
            }
            $data = [];
            //视频评论、点赞、收藏、分享数
            $data['thumb_num'] = array_key_exists('like_num',$val)?$val['like_num']:0;
            $data['comment_num'] = array_key_exists('comment_num',$val)?$val['comment_num']:0;
            $data['watch_num'] = array_key_exists('view_num',$val)?$val['view_num']:0;
            $data['share_num'] = array_key_exists('share_num',$val)?$val['share_num']:0;

            //验证视频是否符合采集需求
            $validateRes = $this->validateNum($data,$jobInfo);
            if ($validateRes == false) {
                continue;
            }

            //平台信息【可不动】
            $data['job_id'] = $jobInfo['id'];
            $data['lang'] = $jobInfo['lang'];
            $data['country'] = $jobInfo['country'];
            $data['paltform'] = $jobInfo['platform'];
            $data['create_by'] = $jobInfo['create_by'];
            $data['create_date'] = date('Y-m-d H:i:s');
            $data['update_by'] = $jobInfo['update_by'];
            $data['update_date'] = date('Y-m-d H:i:s');

            //用户信息
            $data['paltform_uid'] = array_key_exists('uploader_uid',$val)?$val['uploader_uid']:'';//第三方用户ID
            $data['paltform_uname'] = array_key_exists('uploader_name',$val)?$val['uploader_name']:'';//第三方用户名称
            $data['paltform_uhead'] = array_key_exists('uploader_poster',$val)?$val['uploader_poster']:'';//第三方用户头像

            //视频信息
            $data['paltform_vid'] = $val['id'];//第三方视频唯一ID

            $data['video_title'] = $val['title'];//视频标题
            if (checkChinese($data['paltform_uname'] . $data['video_title']) != -1) {
                continue;
            }
            $data['videocover_link'] = $val['poster'];//视频封面
            $data['video_link'] = $val['url'];//视频地址
            $data['video_duration'] = 20000;//视频时长【微妙】
            $data['video_width'] = $val['poster_width'];//视频宽度
            $data['video_height'] = $val['poster_height'];//视频高度
            $data['collect_num'] = 0;//收藏数量
            $data['unlike_num'] = 0;//不喜欢数量
            $data['video_type'] = '';//视频类型
            $data['indescription'] = '';//视频描述
            $data['video_tag'] = '';//视频标签
            $data['publish_date'] = date('Y-m-d H:i:s');//过期时间
            $data['share_url'] = '';//分享地址
            $data['video_widhei_type'] = getVideoSizeType($data['video_width'], $data['video_height']);//判断视频宽高类型
            $data['video_link'] = trim($data['video_link']);
            //判断是否 已经存在
            $isExist = $video->field('id')->where([
                'paltform_vid' => $data['paltform_vid']
            ])->find();
            if ($isExist) {
                $data['id'] = $isExist['id'];
                $updateData[]=$data;
            }else{
                $data['id'] = com_create_guid();//生成唯一UUID

                //判断是否为短视频
                if ($data['video_duration']/1000 <= 90) {
                    $jobRedisData['smallvideo_num'] += 1;//小视频数量+1
                    $data['is_small'] = 1;
                } else {
                    $jobRedisData['shortvideo_num'] += 1;//短视频数量+1
                    $data['is_small'] = 0;
                }

                $jobRedisData['real_quantity'] += 1;//实际采集数量+1
                $insertData[] = $data;
            }

        }
        $video->isUpdate(false)->saveAll($insertData,false);
        $video->isUpdate(true)->saveAll($updateData);
    }

    /**
     * 验证采集数据是否符合条件
     *
     * @param $data
     * @param $jobInfo
     * @return bool
     */
    private function validateNum($data,$jobInfo){
        $res = true;
        $keys = array_keys($data);
        foreach ($keys as $val){
            if($jobInfo[$val]>$data[$val]){
                $res = false;
                break;
            }
        }
        return $res;
    }

    /**
     * AES解密操作
     *
     * @param $data
     * @return string
     */
    protected function parseAes($data)
    {
        $key = 'rz18efAXUbdiaO7k';
        $iv = 'rz18efAXUbdiaO7k';

        //PHP7.1及以上版本使用
        $str = openssl_decrypt(base64_decode($data), "AES-128-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
        $data_str = trim($str);
        return $data_str;
        //PHP7.0及以下版本使用
//        $res = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($data), MCRYPT_MODE_CBC,$iv);

//        return $res;
    }

}